
package com.studiofortress.sf.graphics;

import com.sun.opengl.util.texture.Texture;

/**
 * This is a wrapper for the underlying OpenGL texture. It has some abstraction
 * on top where it pre-calculates values and offers.
 *
 * @author Joseph Lenton
 */
public class GLTexture
{
    private static final GLTextureManager TEXTURE_MANAGER = new GLTextureManager();

    /**
     * @return The texture manager this uses behind the scenes for loading and storing textures.
     */
    public static GLTextureManager getTextureManager()
    {
        return TEXTURE_MANAGER;
    }

    // this is the location of the texture used internally in the GLTextureManager.
    private final int index;

    private boolean isLoaded;

    /**
     * This is the internal private constructor for creating a new GLTexture
     * from the given index.
     * @param index The index number for this texture stored internally in the GLTextureManager.
     */
    private GLTexture(int index)
    {
        this.index = index;

        isLoaded = getInternalTexture().isLoaded();
    }

    /**
     * Creates a new texture from the given path.
     *
     * Note that this is slower then the alternate constructor where the width
     * and height is passed in. If possible that one should be used instead.
     * @param path The path to the texture to load.
     */
    public GLTexture(String path)
    {
        this( TEXTURE_MANAGER.newTexture(path) );
    }

    /**
     * @return True if this texture is loaded and ready for use, otherwise false.
     */
    boolean isLoaded()
    {
        if (!isLoaded) {
            isLoaded = getInternalTexture().isLoaded();
        }
        
        return isLoaded;
    }

    /**
     * Dereferences the texture it uses internally.
     * @throws java.lang.Throwable
     */
    @Override
    protected void finalize() throws Throwable
    {
        super.finalize();
        TEXTURE_MANAGER.dereference(index);
    }

    /**
     * @return The real wrapper for the OpenGL texture which GLTexture represents.
     */
    final GLTextureInner getInternalTexture()
    {
        return TEXTURE_MANAGER.getTexture(index);
    }

    /**
     * @return The intrnal OpenGL texture object that this GLTexture wraps.
     */
    public final Texture getTexture()
    {
        return getInternalTexture().getTexture();
    }

    /**
     * @return The value that represents this texture on the graphics card.
     */
    public final int getTextNum()
    {
        return getInternalTexture().getTextNum();
    }

    /**
     * @return The width of the texture.
     */
    public final int getWidth()
    {
        return getInternalTexture().getWidth();
    }

    /**
     * @return The height of the texture.
     */
    public final int getHeight()
    {
        return getInternalTexture().getHeight();
    }

    /**
     * Internally binds the texture to the corresponding OpenGL pipeline.
     */
    final void bind()
    {
        getInternalTexture().bind();
    }

    /**
     * Internally enables this texture for use with the current OpenGL pipeline.
     */
    final void enable()
    {
        getInternalTexture().enable();
    }

    final void disable()
    {
        getInternalTexture().disable();
    }

    /**
     * @param x The x position of the colour to return.
     * @param y The y position of the colour to return.
     * @return The colour at this pixel as an integer in the format of an INT-ARGB
     * @throws IllegalArgumentException If the x or y co-ordinate is outside of the texture.
     */
    public int getRGB(int x, int y)
    {
        return getInternalTexture().getRGB(x, y);
    }
}
